package com.pisces.tool.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 对象工具类
 */
public class ObjectUtil {

	/**
	 * 判断clazz是否是superClass或其子类
	 *
	 * @param clazz
	 * @param superClass
	 * @return
	 * 创建日期：2012-10-12
	 * 修改说明：
	 * @author 
	 */
	public static boolean isExtends(Class<?> clazz, Class<?> superClass) {
		if(clazz == superClass) {
			return true;
		}
		Class<?> _class = clazz.getSuperclass();
		while (_class != null) {
			if(_class == superClass) {
				return true;
			}
			_class = _class.getSuperclass();
		}
		return false;
	}
	
	/**
	 * 判断clazz是否实现或继承interfaceClass
	 */
	public static boolean isImplement(Class<?> clazz, Class<?> interfaceClass) {
		if(!interfaceClass.isInterface()) {
			return false;
		}
		if(clazz == interfaceClass) {
			return true;
		}
		List<Class<?>> interfaces = new ArrayList<Class<?>>();
		if(clazz.isInterface()) {
			interfaces.addAll(getSuperInterfaces(clazz));
		} else {
			interfaces.addAll(getClassInterfaces(clazz));
		}
		return interfaces.contains(interfaceClass);
	}
	
	/**
	 * @description 获得类的所有属性
	 */
	public static List<Field> getAllField(Class<?> clazz) {
		List<Field> list = new ArrayList<Field>();
		for (Field field : clazz.getDeclaredFields()) {
			list.add(field);
		}
		Class<?> _clazz = clazz.getSuperclass();
		while(_clazz != null) {
			list.addAll(getAllField(_clazz));
			_clazz = _clazz.getSuperclass();
		}
		return list;
	}
	
	/**
	 * 获取一个Class对象的所有字段名
	 */
	public static List<String> getAllFieldNames(Class<?> clazz){
		List<String> list = new ArrayList<String>();
		List<Field> fields = getAllDeclareFields(clazz);
		for (Field field : fields) {
			list.add(field.getName());
		}
		return list;
	}
	
	/**
	 * 获取当前类的所有字段
	 */
	public static List<Field> getAllDeclareFields(Class<?> clazz){
		List<Field> list = new ArrayList<Field>();
		for (Field field : clazz.getDeclaredFields()) {
			list.add(field);
		}
		return list;
	}
	
	/**
	 * 获得类的所有标注了指定的atClass类型注解的属性
	 */
	public static List<Field> getFieldsByAnnotation(Class<?> clazz, Class<? extends Annotation> atClass) {
		List<Field> list = getAllField(clazz);
		List<Field> ret = new ArrayList<Field>();
		for (Field field : list) {
			if(field.getAnnotation(atClass) != null) {
				ret.add(field);
			}
		}
		return ret;
	}

	/**
	 * 获得类的属性和读方法的映射关系
	 */
	public static Map<String, Method> getReadMethodMapping(Class<?> clazz) {
		Map<String, Method> getLowerMapping = new HashMap<String, Method>();
		Map<String, Method> getUpperMapping = new HashMap<String, Method>();
		Map<String, Method> isLowerMapping = new HashMap<String, Method>();
		Map<String, Method> isUpperMapping = new HashMap<String, Method>();
		for (Method method : clazz.getMethods()) {
			if(method.getParameterTypes().length > 0) {
				continue;
			}
			String methodName = method.getName();
			if(method.getReturnType() == boolean.class && methodName.startsWith("is")) {
				if(methodName.matches("^is[a-z_].*$")) {
					isLowerMapping.put(methodName.substring(2), method);
				} else if(methodName.matches("^is[A-Z].*$")) {
					isUpperMapping.put(methodName.substring(2, 3).toLowerCase() + methodName.substring(3), method);
				}
			} else {
				if(methodName.matches("^get[a-z_].*$")) {
					getLowerMapping.put(methodName.substring(3), method);
				} else if(methodName.matches("^get[A-Z].*$")) {
					getUpperMapping.put(methodName.substring(3, 4).toLowerCase() + methodName.substring(4), method);
				}
			}
		}
		for (String field : getUpperMapping.keySet()) {
			getLowerMapping.put(field, getUpperMapping.get(field));
		}
		for (String field : isLowerMapping.keySet()) {
			getLowerMapping.put(field, isLowerMapping.get(field));
		}
		for (String field : isUpperMapping.keySet()) {
			getLowerMapping.put(field, isUpperMapping.get(field));
		}
		return getLowerMapping;
	}


	/**
	 * @description 序列化对象
	 */
	public static byte[] serialize(Object obj) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		try {
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.writeObject(obj);
		    oos.flush();
		    oos.close();
		    return baos.toByteArray();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	    
	}

	/**
	 * @description 反序列化方法
	 */
	public static Object unSerialize(byte[] bytes) {
		Object obj = null;
		ByteArrayInputStream bais = new ByteArrayInputStream(bytes);	
		try {
			ObjectInputStream ois = new ObjectInputStream(bais);
			obj = ois.readObject();
			return obj;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}		 
	}
	
	/**
	 * @description 对象的深层复制，obj的实例类型必须实现序列化接口，否则将抛出异常
	 */
	public static <T> T clone(T obj) {
		@SuppressWarnings("unchecked")
		T ret = (T) unSerialize(serialize(obj));
		return ret; 
	}


	
	/**
	 * 递归获取类的实现接口
	 */
	private static List<Class<?>> getClassInterfaces(
			Class<?> clazz) {
		List<Class<?>> interfaces = new ArrayList<Class<?>>();
		for (Class<?> interface0 : clazz.getInterfaces()) {
			interfaces.addAll(getSuperInterfaces(interface0));
		}
		Class<?> class0 = clazz.getSuperclass();
		while (class0 != null) {
			interfaces.addAll(getClassInterfaces(class0));
			class0 = class0.getSuperclass();
		}
		return interfaces;
	}

	/**
	 * 递归获取指定接口及其继承的接口
	 */
	private static List<Class<?>> getSuperInterfaces(
			Class<?> interface0) {
		List<Class<?>> interfaces = new ArrayList<Class<?>>();
		interfaces.add(interface0);
		for (Class<?> interface1 : interface0.getInterfaces()) {
			interfaces.addAll(getSuperInterfaces(interface1));
		}
		return interfaces;
	}

}
